]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Login/UnlockDialog: don't reset immediately if auth fails
authorGiovanni Campagna <gcampagna@src.gnome.org>
Tue, 7 Aug 2012 14:49:22 +0000 (16:49 +0200)
committerGiovanni Campagna <gcampagna@src.gnome.org>
Tue, 4 Sep 2012 21:38:46 +0000 (23:38 +0200)
Instead of showing a notification, add a small message immediately
below the entry, and give the user two more attempts to login,
before going back to the welcome or lock screen.

https://bugzilla.gnome.org/show_bug.cgi?id=682544

data/theme/gnome-shell.css
js/gdm/loginDialog.js
js/gdm/util.js
js/ui/unlockDialog.js

index 98a69dd104cfa94e17ba62b14047cc6ea5b5b6e3..ec4eabece2739a3e80a7cabb8bc9e96d9f067938 100644 (file)
@@ -2189,6 +2189,10 @@ StButton.popup-menu-item:insensitive {
     background-gradient-end: #74a0d0;
 }
 
+.login-dialog-message-warning {
+    color: orange;
+}
+
 .unlock-dialog-user-name-container {
     spacing: .4em;
 }
index 7bedf451ac5b6af5b47d0748809fb761f5195e57..c6ac0301dcfd3b56125bcf557069c29cec0fdfa0 100644 (file)
@@ -647,7 +647,7 @@ const LoginDialog = new Lang.Class({
 
         this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient);
         this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion));
-        this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
+        this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
         this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
 
         this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
@@ -715,6 +715,10 @@ const LoginDialog = new Lang.Class({
                               x_fill: true,
                               y_fill: false,
                               x_align: St.Align.START });
+
+        this._promptMessage = new St.Label({ visible: false });
+        this._promptBox.add(this._promptMessage, { x_fill: true });
+
         this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' });
         this._promptLoginHint.hide();
         this._promptBox.add(this._promptLoginHint);
@@ -797,6 +801,8 @@ const LoginDialog = new Lang.Class({
     },
 
     _onReset: function(client, serviceName) {
+        this._promptMessage.hide();
+
         let tasks = [this._hidePrompt,
 
                      new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
@@ -826,6 +832,12 @@ const LoginDialog = new Lang.Class({
         this._sessionList.setActiveSession(sessionId);
     },
 
+    _showMessage: function(userVerifier, message, styleClass) {
+        this._promptMessage.text = message;
+        this._promptMessage.styleClass = styleClass;
+        GdmUtil.fadeInActor(this._promptMessage);
+    },
+
     _showLoginHint: function(verifier, message) {
         this._promptLoginHint.set_text(message)
         GdmUtil.fadeInActor(this._promptLoginHint);
@@ -1081,10 +1093,6 @@ const LoginDialog = new Lang.Class({
                              }));
     },
 
-    _onVerificationFailed: function() {
-        this._userVerifier.cancel();
-    },
-
     _onNotListedClicked: function(user) {
         let tasks = [function() {
                          return this._userList.hideItems();
index d2e537a4cc85475f21900f53e46adf05c5a5b680..681c0a69bd028ca6e39d1700062b0152b11087cb 100644 (file)
@@ -2,6 +2,7 @@
 
 const Gio = imports.gi.Gio;
 const Lang = imports.lang;
+const Mainloop = imports.mainloop;
 const Signals = imports.signals;
 
 const Batch = imports.gdm.batch;
@@ -19,6 +20,7 @@ const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
 const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
 const BANNER_MESSAGE_KEY = 'banner-message-enable';
 const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
+const ALLOWED_FAILURES_KEY = 'allowed-failures';
 
 const LOGO_KEY = 'logo';
 
@@ -81,6 +83,8 @@ const ShellUserVerifier = new Lang.Class({
 
         this._fprintManager = new Fprint.FprintManager();
         this._realmManager = new Realmd.Manager();
+
+        this._failCounter = 0;
     },
 
     begin: function(userName, hold) {
@@ -242,7 +246,7 @@ const ShellUserVerifier = new Lang.Class({
             // to indicate the user can swipe their finger instead
             this.emit('show-login-hint', _("(or swipe finger)"));
         } else if (serviceName == PASSWORD_SERVICE_NAME) {
-            Main.notifyError(info);
+            this.emit('show-message', info, 'login-dialog-message-info');
         }
     },
 
@@ -251,7 +255,7 @@ const ShellUserVerifier = new Lang.Class({
         // users who haven't enrolled their fingerprint.
         if (serviceName != PASSWORD_SERVICE_NAME)
             return;
-        Main.notifyError(problem);
+        this.emit('show-message', problem, 'login-dialog-message-warning');
     },
 
     _showRealmLoginHint: function() {
@@ -290,8 +294,10 @@ const ShellUserVerifier = new Lang.Class({
     },
 
     _onReset: function() {
-        this._userVerifier.run_dispose();
-        this._userVerifier = null;
+        this.clear();
+
+        // Clear previous attempts to authenticate
+        this._failCounter = 0;
 
         this.emit('reset');
     },
@@ -300,12 +306,34 @@ const ShellUserVerifier = new Lang.Class({
         this.emit('verification-complete');
     },
 
+    _verificationFailed: function() {
+        // For Not Listed / enterprise logins, immediately reset
+        // the dialog
+        // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
+        // go back to the welcome screen.
+
+        if (!this._userName ||
+            (++this._failCounter) == this._settings.get_int(ALLOWED_FAILURES_KEY)) {
+            // Allow some time to see the message, then reset everything
+            Mainloop.timeout_add(3000, Lang.bind(this, function() {
+                this.cancel();
+
+                this._onReset();
+            }));
+        } else {
+            this.clear();
+            this.begin(this._userName, new Batch.Hold());
+        }
+
+        this.emit('verification-failed');
+    },
+
     _onConversationStopped: function(client, serviceName) {
         // if the password service fails, then cancel everything.
         // But if, e.g., fingerprint fails, still give
         // password authentication a chance to succeed
         if (serviceName == PASSWORD_SERVICE_NAME) {
-            this.emit('verification-failed');
+            this._verificationFailed();
         }
 
         this.emit('hide-login-hint');
index da10cecc15024157a2d8e56146869f73d538f53d..b18c18da0c19643290cba6554b04e678456c805a 100644 (file)
@@ -89,13 +89,15 @@ const UnlockDialog = new Lang.Class({
         this._userName = GLib.get_user_name();
         this._user = this._userManager.get_user(this._userName);
 
+        this._failCounter = 0;
+
         this._greeterClient = new Gdm.Client();
         this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
 
-        this._userVerifier.connect('reset', Lang.bind(this, this._reset));
         this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
+        this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
         this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
-        this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
+        this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
 
         this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
         this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
@@ -122,6 +124,9 @@ const UnlockDialog = new Lang.Class({
 
         this.contentLayout.add_actor(this._promptLayout);
 
+        this._promptMessage = new St.Label({ visible: false });
+        this.contentLayout.add(this._promptMessage, { x_fill: true });
+
         this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' });
         this._promptLoginHint.hide();
         this.contentLayout.add_actor(this._promptLoginHint);
@@ -135,7 +140,6 @@ const UnlockDialog = new Lang.Class({
         this.setButtons([cancelButton, this._okButton]);
 
         this._updateOkButton(false);
-        this._reset();
 
         let otherUserLabel = new St.Label({ text: _("Log in as another user"),
                                             style_class: 'login-dialog-not-listed-label' });
@@ -150,6 +154,9 @@ const UnlockDialog = new Lang.Class({
                               { x_align: St.Align.START,
                                 x_fill: false });
 
+        let batch = new Batch.Hold();
+        this._userVerifier.begin(this._userName, batch);
+
         GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
             this.emit('loaded');
             return false;
@@ -165,9 +172,10 @@ const UnlockDialog = new Lang.Class({
         this._okButton.button.reactive = sensitive;
     },
 
-    _reset: function() {
-        this._userVerifier.clear();
-        this._userVerifier.begin(this._userName, new Batch.Hold());
+    _showMessage: function(userVerifier, message, styleClass) {
+        this._promptMessage.text = message;
+        this._promptMessage.styleClass = styleClass;
+        GdmUtil.fadeInActor(this._promptMessage);
     },
 
     _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
@@ -207,13 +215,13 @@ const UnlockDialog = new Lang.Class({
         this.emit('unlocked');
     },
 
-    _onVerificationFailed: function() {
-        this._userVerifier.cancel();
+    _onReset: function() {
         this.emit('failed');
     },
 
     _escape: function() {
-        this._onVerificationFailed();
+        this._userVerifier.cancel();
+        this.emit('failed');
     },
 
     _otherUserClicked: function(button, event) {